/**
 * 
 */
package com.oet.persistence.operator;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;

import com.oet.persistence.entity.Category;
import com.oet.persistence.entity.CourseSeries;
import com.oet.persistence.entity.Teacher;
import com.persistence.template.QueryOperator;

/**
 * @author Zhang Yu
 *
 */
public class CourseSeriesQuery extends QueryOperator<CourseSeries> {
	
	public static final String[] COURSE_SERIES_MULTI_SEARCH_ALL 
	={ 
		" (:Param0) = (:ParamValue0)",
		" (:Param1) = (:ParamValue1)",
		" (:Param2) = (:ParamValue2)",
		" (:Param3) = (:ParamValue3)",
		" (:Param4) = (:ParamValue4)",
		" (:Param5) like concat('%', concat(lower(:ParamValue5),'%'))",
		" (:Param6) like concat('%', concat(lower(:ParamValue6),'%'))",
		" (:Param7) like concat('%', concat(lower(:ParamValue7),'%'))",
		" (:Param8) like concat('%', concat(lower(:ParamValue8),'%'))",
		" (:Param9) like concat('%', concat(lower(:ParamValue9),'%'))",
		" (:Param10) like concat('%', concat(lower(:ParamValue10),'%'))",
		" (:Param11) like concat('%', concat(lower(:ParamValue11),'%'))",
		" (:Param12) like concat('%', concat(lower(:ParamValue12),'%'))",
		" (:Param13) like concat('%', concat(lower(:ParamValue13),'%'))",
	};
	
	public static final String  MULTI_EJBQL=
		"select courseSeries from com.oet.persistence.entity.CourseSeries courseSeries";
	public static final String COURSE_SERIES_MULTI_EJBQL_TAG = " left outer join courseSeries.bookTags as booktag";
	public static final String COURSE_SERIES_MULTI_EJBQL_TX = " left outer join courseSeries.transactions as tx";
	
	
	public CourseSeriesQuery(EntityManager em)
	{
		setEntityManager(em);
		validate();
		setMaxResults(CourseSeriesQuery.MAX_RESULTS_NUM);
		//Explicitly set the searching rule
		setUserRestrictions(CASE_INSENSITIVE_RESTRICTION_SEARCH);
	}
	
	
	public CourseSeriesQuery(EntityManager em, String courseSeriesName)
	{
		setEntityManager(em);
		validate();
		clearRestrictions();
		clearAllParameters();
		setMaxResults(CourseSeriesQuery.MAX_RESULTS_NUM);
		//Explicitly set the searching rule
		setUserRestrictions(CASE_INSENSITIVE_RESTRICTION_SEARCH);
		addRestrictionParameter("name", courseSeriesName);
	}
	
	public CourseSeriesQuery(EntityManager em, String ejbql, String ristriction)
	{
		setEntityManager(em);
		validate();
		setMaxResults(CourseSeriesQuery.MAX_RESULTS_NUM);
		//Explicitly set the searching rule
		setUserRestrictions(CASE_INSENSITIVE_RESTRICTION_SEARCH_ALL);
		
		setEjbql(ejbql);
		if (ristriction != null)
		addRestrictions(ristriction);
	}
	/* (non-Javadoc)
	 * @see com.assetKeeper.server.template.QueryOperator#getEntityClassName()
	 */
	@Override
	public String getEntityClassName() {
		// TODO Auto-generated method stub
		return CourseSeries.class.getSimpleName();
	}
	
	@Override
	public String getWholeEntityClassName() {
		// TODO Auto-generated method stub
		//return User.class.getSimpleName();
		return "com.oet.persistence.entity.CourseSeries";
	}
	
	/*
	 * Search User with specified field
	 */
	public List<CourseSeries> searchCourseSeriesByField(String name, Object value)
	{
		clearRestrictions();
		clearAllParameters();
		setMaxResults(CourseSeriesQuery.MAX_RESULTS_NUM);
		setUserRestrictions(CASE_INSENSITIVE_RESTRICTION_SEARCH_ALL);
		addRestrictionParameter(name, value);
		List<CourseSeries> list = getResultList();
		
		logger.debug("searchCourseSeriesByField: size:" + list.size());
		
		return list;
	}
	
	
	/*
	 * Search User with specified field
	 */
	public CourseSeries searchCourseSeriesById(String stringId)
	{
//		logger.debug("searchCourseSeriesById: stringId " + stringId);
//		if (stringId == null || stringId.isEmpty())
//		{
//			return null;
//		}
//		setQueryAttribute(CASE_SENSITIVE_RESTRICTION_SEARCH);
//		addRestrictionParameter("courseSeriesId", stringId);
//		List<CourseSeries> list = getResultList();
//		if (list != null && list.size() >= 1)
//		{
//			return list.get(0);
//		}
		return null;
	}
	
	
	public List<CourseSeries> searchCourseSeriesByMultiField(
			String name, Category category, 
			Integer level, Integer courseNumber, Teacher teacher,
			Integer capacity, Integer occupyNum, Date startDate, Date endDate, 
			Boolean isActived, Double totalPrice,
			Integer weekdayFlagStart, 
			Integer weekdayFlagEnd, Integer timeFlag, Boolean isAvailable)
	{

		setEjbql(MULTI_EJBQL);
		setQueryAttribute(null);
		setRestrictions(new ArrayList<String>(0));
		
		int i = 0;
		
		if (name != null && !name.isEmpty())
		{
			addRestrictionParameter("courseSeries.name", name);
			addRestrictions(" (:Param" + i 
				+ ") like concat('%', concat(lower(:ParamValue" +i 
				+"),'%'))");
			i++;
		}
		
		if (category != null && category.getId() != null)
		{
			addRestrictionParameter("courseSeries.category", category);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		
		if (level != null)
		{
			addRestrictionParameter("courseSeries.level", level);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		
		if (courseNumber != null)
		{
			addRestrictionParameter("courseSeries.courseNumber", courseNumber);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		
		if (teacher != null && teacher.getId() != null)
		{
			addRestrictionParameter("courseSeries.teacher", teacher);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		
		if (capacity != null)
		{
			addRestrictionParameter("courseSeries.capacity", capacity);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		
		if (occupyNum != null)
		{
			addRestrictionParameter("courseSeries.occupyNum", occupyNum);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		
		if (totalPrice != null)
		{
			addRestrictionParameter("courseSeries.totalPrice", totalPrice);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		
		if (isActived != null)
		{
			addRestrictionParameter("courseSeries.isActived", isActived);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}

		
		if (startDate != null )
		{
			addRestrictionParameter("courseSeries.endDate", startDate);
			addRestrictions(" (:Param"+i+") >= (:ParamValue" +i +")");
			i++;
		}
		
		if (endDate != null )
		{
			addRestrictionParameter("courseSeries.startDate", endDate);
			addRestrictions(" (:Param"+i+") <= (:ParamValue" +i +")");
			i++;
		}
		
		if (weekdayFlagStart != null )
		{
			addRestrictionParameter("courseSeries.weekdayFlag", weekdayFlagStart);
			addRestrictions(" (:Param"+i+") >= (:ParamValue" +i +")");
			i++;
		}
		
		if (weekdayFlagEnd != null )
		{
			addRestrictionParameter("courseSeries.weekdayFlag", weekdayFlagEnd);
			addRestrictions(" (:Param"+i+") <= (:ParamValue" +i +")");
			i++;
		}
		
		if (timeFlag != null )
		{
			addRestrictionParameter("courseSeries.timeFlag", timeFlag);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		
		if (isAvailable != null && isAvailable)
		{
			addRestrictionParameter("courseSeries.isActived", true);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
			addRestrictions(" (courseSeries.occupyNum) < (courseSeries.capacity)");
		}
		
		
		/*
		if (author != null && author.getId() != null)
		{
			addRestrictionParameter("book.author", author);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		if (pubisher != null && pubisher.getId() != null)
		{
			addRestrictionParameter("book.publisher", pubisher);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		if (category != null && category.getId() != null)
		{
			addRestrictionParameter("book.category", category);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		if (bookTag != null && bookTag.getId() != null)
		{
			setEjbql(getEjbql() + BOOK_MULTI_EJBQL_BOOKTAG);
			addRestrictionParameter("booktag", bookTag);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		if (partner != null && partner.getId() != null)
		{
			setEjbql(getEjbql() + BOOK_MULTI_EJBQL_TX);
			addRestrictionParameter("tx.partner", partner);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		
		if (reader != null && reader.getId() != null)
		{
			if (partner != null && partner.getId() != null)
			{
			}
			else
			{
				setEjbql(getEjbql() + BOOK_MULTI_EJBQL_TX);
			}
			addRestrictionParameter("tx.reader", reader);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}
		*/
		this.setOrderDesc("id");
		
		return getResultList();
	}
	
	
//	public List<CourseSeries> searchCourseSeriesInLibrary(Library lib)
//	{
//		setEjbql(BOOK_MULTI_EJBQL);
//		setQueryAttribute(null);
//		setRestrictions(new ArrayList<String>(0));
//		
//		int i = 0;
//		
//		if (lib != null && lib.getId() != null)
//		{
//			addRestrictionParameter("book.category.library", lib);
//			addRestrictions(" (:Param" + i 
//				+ ") like concat('%', concat(lower(:ParamValue" +i 
//				+"),'%'))");
//			i++;
//		}
//		
//		
////		addRestrictionParameter("book.category.library", lib);
////		addRestrictions(" (:Param" + i 
////				+ ") like concat('%', concat(lower(:ParamValue" +i 
////				+"),'%'))");
////			i++;
//		
//		setOrderDesc("id");
//	
//		return getResultList();
//	}
	
	public List<CourseSeries> searchCourseSeriesInList(List<Long> ids)
	{
		setEjbql(MULTI_EJBQL);
		setQueryAttribute(null);
		setRestrictions(new ArrayList<String>(0));
		
		
		addRestrictionParameter("courseSeries.id", ids);
		addRestrictions(" (:Param0) in (:ParamValue0)");
		
//		this.setOrderDesc("id");
		setOrderDesc("id");
		return getResultList();
	}
	
	public List<CourseSeries> searchCourseSeries(List<Long> ids)
	{
		setEjbql(MULTI_EJBQL);
		setQueryAttribute(null);
		setRestrictions(new ArrayList<String>(0));
		
		addRestrictionParameter("courseSeries.id", ids);
		addRestrictions(" (:Param0) in (:ParamValue0)");
		
		setOrderDesc("id");
		return getResultList();
	}
	
	public List<CourseSeries> searchCourseSeriess()
	{
		setEjbql(MULTI_EJBQL);
		setQueryAttribute(null);
		setRestrictions(new ArrayList<String>(0));
		
		setOrderDesc("id");
		return getResultList();
	}
	
	public List<CourseSeries> searchCourseSeriess(Integer maximum)
	{
		setEjbql(MULTI_EJBQL);
		setQueryAttribute(null);
		setRestrictions(new ArrayList<String>(0));
		
		if (maximum != null && maximum >= 1)
		{
			setMaxResults(maximum);
		}
		
		setOrderDesc("id");
		return getResultList();
	}
	

	public List<CourseSeries> searchCourseSeriesInCategory(Category category)
	{
		setEjbql(MULTI_EJBQL);
		setQueryAttribute(null);
		setRestrictions(new ArrayList<String>(0));
		
		int i = 0;
		
		if (category != null && category.getId() != null)
		{
			addRestrictionParameter("courseSeries.category", category);
			addRestrictions(" (:Param"+i+") = (:ParamValue" +i +")");
			i++;
		}	
		setOrderDesc("id");
	
		return getResultList();
	}

}
